<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
 <meta name="Page-topic" content="ST-Open Tutorials: Grundlagen" />
 <meta name="Description" content="ST-Open Tutorials: Grundlagen" />
 <meta name="Keywords" content="ST-Open Weichwaren, Open Quelle, ST-Open, Weichwaren, Bibliothek, Bibliotheken, freie Weichwaren, Assembler, C" />
 <meta name="date" content="2012-01-01T00:00:00+00:00" />
 <meta name="robots" content="index,follow" />
 <meta name="revisit-after" content="14 days" />
 <meta name="generator" content="Bernhard Schornak, handwritten" />
 <style type="text/css"><!--@import "../../st.css";--></style>
 <link rel="SHORTCUT ICON" href="../../../../pics/favicon.ico" />
 <title>Grundlagen</title>
</head>
<body id="top">
<div class="pagehd">
<div id="menu">
<ul>
 <li><a href="../../../index.htm">Weichwaren</a></li>
 <li><a href="../tut/index.htm">Tutorials</a></li>
 <li><a href="../index.htm">Dokumentation</a></li>
 <li><a href="../alp.htm">alphabetisch</a></li>
 <li><a href="../fct.htm">nach Funktion</a></li>
</ul>
</div>
<div class="update">[2012-01-01]</div>
<div class="headpc"><img src="../../pics/ste.png" alt="QuelleDoc Logo" width="75" height="75" border="0" /></div>
</div>
<div class="crlf1"></div>
&#160;&#160;&#160;<a href="index.htm"><img src="../../../../pics/nav_up.png" alt="aufw&auml;rts" width="20" height="20" border="0" title="aufw&auml;rts" /></a>
&#160;&#160;&#160;<a href="0502.htm"><img src="../../../../pics/nav_bk.png" alt="zur&uuml;ck" width="20" height="20" border="0" title="zur&uuml;ck" /></a>
&#160;&#160;&#160;<a href="0504.htm"><img src="../../../../pics/nav_fw.png" alt="vorw&auml;rts" width="20" height="20" border="0" title="vorw&auml;rts" /></a>
&#160;&#160;&#160;<a href="FFFF.htm">Glossar</a>
<div class="crlf1"></div>
<div class="text100">
<h1>Grundlagen</h1>
Nach der Definition des Feldkopfes widmen wir uns nun den Grundlagen der Datenbankmaschine.
 Da Datenbankmaschine aufgrund der L&auml;nge etwas unkommod zu handhaben ist, k&uuml;rzen
 wir das Wort ab sofort mit DBE (f&uuml;r <i>database engine</i> = Datenbankmaschine) ab.
 Alle im Text angegebenen Abst&auml;nde beziehen sich <i>prinzipiell</i> auf die Adresse,
 die nach dem Aufruf von LDreq() im Mitglied MemEA der LD-Struktur zur&uuml;ckgegeben wird.
 Dies ist die Adresse des Speicherblocks, in dem unser Datenfeld vom Lader abgelegt wurde.
 Bitte verwechseln Sie das Mitglied MemEA nicht mit dem Mitglied MMoff, dem Speicherhenkel
 des Feldes. Die DBE wird immer mit dem Speicherhenkel angesprochen, aus dem sie dann die
 tats&auml;chliche Adresse des Feldes ausliest. Zugriffe der DBE erfolgen ausschliesslich
 auf das Datenfeld, aus dem angeforderte Daten gelesen oder in das Daten hineingeschrieben
 werden.
<div class="crlf1"></div>
Der Feldkopf enth&auml;lt alle Informationen, die die DBE zur Erledigung aller anfallenden
 Aufgaben ben&ouml;tigt. 00[MemEA] jedes Datenfeldes enth&auml;lt immer 32 Byte mit einem
 Inhalt von Null. Es ist einerseits die Adresse einer leeren Zeichenkette, wird von einigen
 Systemfunktionen aber auch zu Pr&uuml;fzwecken abgefragt. Stehen hier 32 Nullen, und die
 Feldnummer auf Abstand 2C entspricht der im Speicherhenkel stehenden Feldnummer, handelt
 es sich mit gr&ouml;sster Wahrscheinlichkeit um ein g&uuml;ltiges Datenfeld. Es folgt der
 optionale Feldname, der in unserem Beispiel freigelassen wurde. 20[MemEA] stellt f&uuml;r
 einige Funktionen die maximale Gr&ouml;sse der einzelnen Unterfelder bereit, auf 24[MemEA]
 ist die Anzahl der Datentypen = Unterfelder abgelegt. In unserem Beispiel sind es zwei -
 das erste enth&auml;lt Daten des Typs 01 (Byte), das zweite Daten des Typs 07 (dynamische
 Zeichenketten). 28[MemEA] enth&auml;lt ein Doppelwort mit Kontrolldaten f&uuml;r SecSys.
 Da hier eine Null steht, wird dieses Datenfeld offensichtlich nicht vom Sicherheitssystem
 &uuml;berwacht. 2C[MemEA] enth&auml;lt die Feldnummer, in unserem Fall 00000001. 30[MemEA]
 ist das Statuswort des Feldes. 0x0027 sagt uns, dass wir lese- und schreibberechtigt sind,
 der Inhalt dieses Datenfeldes sich ge&auml;ndert hat und das Feld bis zu seiner expliziten
 Freigabe permanent im Speicher verbleiben muss. 32[MemEA] und 33[MemEA] werden ignoriert,
 da das Feld nicht von SecSys verwaltet wird. 34[MemEA] ist die momentane Feldgr&ouml;sse,
 hier 352 Byte. 38[MemEA] bestimmt die maximale Gr&ouml;sse aller Eintr&auml;ge im Feld,
 in unserem Beispiel 32 Byte. 3C[MemEA] gibt die Anzahl der Eintr&auml;ge im Datenfeld an,
 unser Feld enth&auml;lt demnach 16 Eintr&auml;ge in jedem Unterfeld. Damit haben wir das
 Ende des Informationsbereichs erreicht.
<div class="crlf1"></div>
Ab 40[MemEA] folgt die 32 Byte grosse Typentabelle. Unser Feld hat demnach zwei Unterfelder
 mit den Typen 01 und 07. Alle im Feld enthaltenen Datentypen werden in fortlaufender Folge
 aufgez&auml;hlt. Nicht ben&ouml;tigte Eintr&auml;ge enthalten den Wert Null, was f&uuml;r
 "kein Typ" steht - definierte Datentypen haben immer einen Wert ungleich Null.
<div class="crlf1"></div>
Ab 60[MemEA] beginnt die 128 Byte grosse Tabelle mit den Abst&auml;nden aller Unterfelder.
 Bitte verwechseln Sie diese Tabelle nicht mit den Abstandstabellen von Zeichenketten, die
 sp&auml;ter noch beschrieben werden!
<div class="crlf1"></div>
Betrachten wir den Feldaufbau von einer anderen Perspektive, f&auml;llt schnell auf, dass
 der Feldkopf nach streng logischen Gesichtspunkten definiert wurde. Die DBE kann mit sehr
 wenigen Zugriffen schnellstm&ouml;glich auf alle Verwaltungsdaten zugreifen, ohne Zeit mit
 aufw&auml;ndigen Berechnungen verschenken zu m&uuml;ssen. Numerische Daten lassen sich bis
 zu einer Breite von 64 Bit ausschliesslich mit indirekter, indizierter Adressierung lesen
 und schreiben. Bei gr&ouml;sseren Bitbreiten gen&uuml;gt eine einzige Multiplikation, um
 den Abstand jedes Eintrags zu ermitteln. Einzig die dynamischen Zeichenketten erfordern
 eine zeitintensivere Behandlung bei Schreibzugriffen, da die DBE bestehende Eintr&auml;ge
 gegebenenfalls aus dem Feld l&ouml;scht und eine M&uuml;llsortierung (garbage collection)
 ausf&uuml;hrt, bevor die zu schreibende Zeichenkette an das Feldende angeh&auml;ngt wird.
 Somit wird das Feld immer auf dem kleinstm&ouml;glichen Stand gehalten, es enth&auml;lt
 auch niemals "Leichen" alter Zeichenketten, die irgendwann einmal in das Feld geschrieben
 wurden. Ist h&ouml;chste Geschwindigkeit gefragt, kann man auch auf Festl&auml;ngenblocks
 ausweichen, die dann ausschliesslich &uuml;ber ihre Adresse angesprochen werden, um das
 mehrfache Umkopieren von Zeichenketten bei Lese- <i>und</i> Schreiboperationen zu umgehen.
 Mit den dynamischen Zeichenketten ist das wegen ihrer variablen Gr&ouml;sse und der
 M&uuml;llsortierung <i>nur</i> bei Lesezugriffen angeraten, da durch den Programmierer
 vorgenommene Schreibzugriffe schnell zu Inkonsistenz des Feldes und defekten Zeichenketten
 f&uuml;hren d&uuml;rften. Ist das einmal geschehen, k&ouml;nnen Sie das Feld getrost auf
 den Reisswolf ziehen - der n&auml;chste Absturz ist nur eine Frage der Zeit.
<div class="crlf1"></div>
<h2>Zusammenh&auml;nge</h2>
<div class="limage"><img src="../../pics/doc0004.png" alt="Feldaufbau" width="300" height="300" border="0" /></div>
Die Graphik veranschaulicht die Zusammenh&auml;nge zwischen den im Feldkopf festgehaltenen
 Informationen. Alle farblich hervorgehobenen Bereiche gleicher Farbe haben einen direkten
 Bezug zueinander. Der Inhalt des Bytes auf 40[MemEA] legt den Datentyp, das von 60[MemEA]
 gelesene Doppelwort den Abstand des ersten, von 0100[MemEA] bis 010F[MemEA] angelegten
 Unterfeldes fest. Das zweite Unterfeld enth&auml;lt die bereits angesprochenen dynamischen
 Zeichenketten. Das Unterfeld selbst enth&auml;lt hierbei nur eine Abstandstabelle, die der
 DBE angibt, ab welchem Abstand im Feld die Zeichenkette gespeichert ist. Wurde in einem
 Eintrag noch keine Zeichenkette abgelegt, oder die Zeichenkette wurde gel&ouml;scht, ist
 der Abstand Null. Wie bereits besprochen, ist auf Abstand Null ein Block mit 32 Nullen,
 auch als leere Zeichenkette bekannt, gespeichert. Wird eine Zeichenkette in einen bisher
 leeren Eintrag geschrieben, wird diese an das Feldende angeh&auml;ngt, und die neue
 Feldgr&ouml;sse wird im Doppelwort 34[MemEA] festgehalten. Ist bereits eine Zeichenkette
 unter der Eintragsnummer gespeichert (Offset ungleich Null), wird sie &uuml;berschrieben,
 sofern sie (einschliesslich der abschliessenden Null) in den f&uuml;r diesen Eintrag
 reservierten Bereich passt. Ist die neue Zeichenkette zu gross, wird sie durch Verschieben
 des gesamten dar&uuml;berliegenden Feldinhaltes an den alten Abstand gel&ouml;scht und ihr
 Abstand wird auf Null gesetzt. Alle Abst&auml;nde werden korrigiert, wenn sie oberhalb des
 alten Abstands lagen. Erst nach dieser M&uuml;llsortierung wird die neue Zeichenkette an
 das Feldende geschrieben. Zum Abschluss der Aktion erfolgt noch die notwendige Korrektur
 der Feldgr&ouml;sse und das Sichern des neuen Abstands in der Abstandstabelle. Bevor die
 DBE mit einer Schreiboperation beginnt, setzt sie das "schmutzig"-F&auml;hnchen (dirty
 flag) im Statuswort. Es wird von erst dann zur&uuml;ckgesetzt, wenn der Schreibvorgang
 fehlerfrei beendet wurde. So lange dieses F&auml;hnchen gesetzt ist, verweigert die DBE
 alle weiteren Schreibzugriffe, und der Lader schliesst das Feld bei der Freigabe, ohne
 seinen Inhalt zu sichern. In den sechs Jahren, die seit Einf&uuml;hrung dieser Sicherung
 vergangen sind, ist noch keines meiner Felder diesem Mechanismus anheim gefallen. Das
 heisst nicht, dass er aus Versehen nicht doch einmal gewaltig zuschlagen k&ouml;nnte.
<div class="crlf1"></div>
&Uuml;bersteigt die Gr&ouml;sse einer zum Schreiben &uuml;bergebenen Zeichenkette die in
 38[MemEA] festgelegte Gr&ouml;sse, wird die Zeichenkette so abgeschnitten, dass sie mit
 der terminierenden Null zusammen genau die maximale Gr&ouml;sse hat. In unserem Beispiel
 w&uuml;rde eine 40 Byte grosse Zeichenkette auf 31 Byte plus Null = 32 Byte gek&uuml;rzt,
 bevor sie an das Feldende angeh&auml;ngt wird. Zeichenketten werden prinzipiell auf eine
 L&auml;nge erweitert, die einem ganzzahligen Vielfachen von 16 entspricht. Durch diese
 Anpassung kann die DBE Oktoworte statt Byte kopieren, was alle Kopiervorg&auml;nge um ein
 Vielfaches beschleunigt (SSE- oder AVX-Zugriffe).
<div class="crlf1"></div>
<h2>Anwendung</h2>
Die DBE ist ein Funktionsverteiler mit Unterfunktionen, der mit dem Aufruf
<div class="crlf1"></div>
<div class="box100">
<b>Ergebnis = FDacc(Speicherhenkel, Eintrag, Unterfeld, Funktion, Adresse, Zahl);</b>
</div>
<div class="crlf1"></div>
angesprochen wird. F&uuml;r die R&uuml;ckgabe von Adressen hat FDacc() den Namen FDvpt():
<div class="crlf1"></div>
<div class="box100">
<b>Adresse = FDvpt(Speicherhenkel, Eintrag, Unterfeld, Funktion, Adresse, Zahl);</b>
</div>
<div class="crlf1"></div>
FDvpt() ist keine zweite Funktion, sondern nur eine zus&auml;tzliche Deklaration f&uuml;r
 C-Programmierer. Sie vermeidet die von C-Kompilierern vorgenommenen Typumwandlungen, die
 teilweise sehr aufw&auml;ndig (und auf abenteuerlichen Wegen) Doppelworte in Doppelworte
 umwandeln. <i>Intelligent Design</i>-Programmierer haben es hier etwas leichter, da sie
 durchgehend mit _FDacc arbeiten k&ouml;nnen...
<div class="crlf1"></div>
<h3>Parameter</h3>
<h4>Ausgabe: Ergebnis</h4>
Ein Ergebnis wird nur f&uuml;r die Typen 01 bis 04, respektive von der Unterfunktion
 FDA_OFFSET, zur&uuml;ckgeliefert. F&uuml;r alle anderen Datentypen ist dieses Ergebnis
 irrelevant, da sich Daten mit einer Breite jenseits von 64 Bit nicht in einem 64 Bit
 breiten Register darstellen lassen. Nichtsdestotrotz wird das Ergebnis der Typen 05 bis
 07 generell auf Null gesetzt. Sollte das nicht der Fall sein, w&auml;re ich sehr erfreut,
 wenn Sie mir eine kurze Mitteilung schicken, da das auf Fehler in der entsprechenden
 Unterfunktion hinweist.
<div class="crlf1"></div>
<h4>Ausgabe: Adresse</h4>
FDvpt() gibt immer die Adresse des spezifizierten Eintrags zur&uuml;ck. Ist einer der an
 FDvpt() &uuml;bergebenen Parameter ung&uuml;ltig, dann liefert FDvpt() die Feldadresse an
 den Aufrufer zur&uuml;ck, um Abst&uuml;rze wegen ung&uuml;ltiger Adressen zu vermeiden.
 Wie bereits besprochen, liegt am Feldanfang ein Doppelwort mit dem Inhalt Null. F&uuml;r
 die Datentypen 01 bis 05 und 07 ist das ein g&uuml;ltiger R&uuml;ckgabewert. Beim Typ 06
 (Festl&auml;ngenblock) sollte man generell pr&uuml;fen, ob die zur&uuml;ckgelieferte
 Adresse identisch mit der Feldadresse ist. Schreiboperationen in den Feldkopf vermindern
 zwangsl&auml;ufig die Konsistenz des Feldes.
<div class="crlf1"></div>
<h4>Eingabe: Speicherhenkel</h4>
Der Speicherhenkel des Feldes. Dies ist das Mitglied <b>MMoff</b> der LD-Struktur, die sie
 dem Lader bei der Anforderung des Feldes &uuml;bergeben haben. Er sollte gleich nach der
 Anforderung in eine globale Variable kopiert werden, damit Sie die DBE ansprechen und das
 Feld nach seiner Verwendung mittels LDfre() wieder freigeben k&ouml;nnen.
<div class="crlf1"></div>
<h4>Eingabe: Eintrag</h4>
Die Nummer des Eintrags. Bei einigen Unterfunktionen ist dies die Nummer des Zieleintrags!
<div class="crlf1"></div>
<h4>Eingabe: Unterfeld</h4>
Die Nummer des Unterfeldes. Bei Feldern mit nur einem Datentyp ist das prinzipiell Null,
 bei zwei Datentypen Null oder Eins, und so weiter.
<div class="crlf1"></div>
<h4>Eingabe: Funktion</h4>
Eine der definierten FDA_*-Funktionen.
<div class="crlf1"></div>
<h4>Eingabe: Adresse</h4>
Dieser Parameter ist optional. Er wird generell nur f&uuml;r Datentypen ben&ouml;tigt, die
 breiter als 32 Bit sind.
<div class="crlf1"></div>
<h4>Eingabe: Zahl</h4>
F&uuml;r FDA_WRITE wird hier der Wert des zu schreibenden Bytes, Wortes, Doppelwortes oder
 Vierfachwortes &uuml;bergeben. Bei einigen anderen Unterfunktionen &uuml;bergibt man in
 diesem Parameter die Nummer des Quelleintrages.
<div class="crlf2"></div>
Soviel zu den Grundlagen der Datenbankmaschine. Es g&auml;be bestimmt noch einige Dinge zu
 erg&auml;nzen. Das Tutorial soll aber nicht zum ausgewachsenen Buch mutieren, so dass ich
 langsam einen Schlu&szlig;strich ziehe und Sie an die Anleitung zur praktischen Anwendung
 der DBE weiterleite.
</div>
<div class="crlf2"></div>
&#160;&#160;&#160;<a href="index.htm"><img src="../../../../pics/nav_up.png" alt="aufw&auml;rts" width="20" height="20" border="0" title="aufw&auml;rts" /></a>
&#160;&#160;&#160;<a href="0502.htm"><img src="../../../../pics/nav_bk.png" alt="zur&uuml;ck" width="20" height="20" border="0" title="zur&uuml;ck" /></a>
&#160;&#160;&#160;<a href="0504.htm"><img src="../../../../pics/nav_fw.png" alt="vorw&auml;rts" width="20" height="20" border="0" title="vorw&auml;rts" /></a>
<div class="crlf1"></div>
&#160;&#160;&#160;<a href="http://validator.w3.org/check?uri=http%3A%2F%2Fst-open.com%2Fst-open%2Fdoc%2Fd%2Ftut%2F0503.htm">
<img src="../../../../pics/xhtml.png" alt="validHTML" width="100" height="35" border="0" title="XHTML pr&uuml;fen" /></a>
<div class="crlf1"></div>
</body>
</html>
